package com.qdlc.p2p.biz.service.lottery;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

import com.qdlc.p2p.biz.zdata.LotteryResult;
import com.qdlc.p2p.common.exception.BusinessException;
import com.qdlc.p2p.common.exception.UserException;
import com.qdlc.p2p.common.util.BeanCopierUtils;
import com.qdlc.p2p.dal.dto.Lottery;

/**
 * Created by hongbl on 2016/2/2.
 *
 * 创建抽奖算法工厂，将原来在AbstractLotteryService里的算法剥离出来
 *
 *
 */
public class LotteryAlgorithmFactory {

    /**
     *获取抽奖结果
     */
    public static LotteryResult getResult(List<Lottery> lotteryConfig){
        if (null == lotteryConfig || lotteryConfig.isEmpty()) {
            throw new UserException("无法抽奖,请联系管理员！", BusinessException.TYPE_JSON);
        }
        // 保存概率列表
        int size = lotteryConfig.size();
        List<Double> orignalRates = new ArrayList<Double>(size);
        for (Lottery config : lotteryConfig) {
            orignalRates.add(config.getRate());
        }
        int index = drawLotteryAlgorithm(orignalRates);
        if (index == -1) { // 未设置中奖概率
            throw new UserException("无法抽奖,请联系管理员！", BusinessException.TYPE_JSON);
        }
        Lottery lottery = lotteryConfig.get(index);
        // 抽奖结果保存
        LotteryResult lotteryResult = new LotteryResult();
        BeanCopierUtils.copyProperties(lottery, lotteryResult);
        LotteryMessageFactory.setMessage(lotteryResult);
        return lotteryResult;
    }


    /**
     *计算中奖区域
     */
    public static int  drawLotteryAlgorithm(List<Double> orignalRates) {
        // 计算总概率，这样可以保证不一定总概率是1
        double sumRate = 0d;
        for (double rate : orignalRates) {
            sumRate += rate;
        }
        // 未设置中奖概率
        if(sumRate == 0d) return -1;
        // 计算每个物品在总概率的基础下的概率情况
        List<Double> sortOrignalRates = new ArrayList<Double>(orignalRates.size());
        Double tempSumRate = 0d;
        for (double rate : orignalRates) {
            tempSumRate += rate;
            sortOrignalRates.add(tempSumRate / sumRate);
        }
        // 根据区块值来获取抽取到的物品索引
        double nextDouble = Math.random();
        sortOrignalRates.add(nextDouble);
        Collections.sort(sortOrignalRates);
        // 找出中奖索引位置 就是中奖结果
        return sortOrignalRates.indexOf(nextDouble);
    }
}
